#ifndef __WFW_LOGWRITER_H
#define __WFW_LOGWRITER_H

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <string>
using namespace std;

class WFW_LogWriter
{
private:
	char* buffer;
	int bufSize;
	int writePos;
	int readPos;
	pthread_mutex_t mutex;
	int m_fd;
	bool isFull;
	bool isStopped;
	pthread_t m_readerThread;

protected :
	enum enLogStatus
	{
		stInitial,
		stRuning
	};
	enLogStatus m_status;
	
	enum
	{
		//Log文件的最大Size
		MAX_FILE_SIZE = 16 * 1024 * 1024,
		
		//Log文件的最大个数
		MAX_FILE_NUM = 999,
		
		//当buffer写满时，每次检查buffer状态等待的时间
		WAIT_INTERVAL_WHEN_BUF_FULL = 50, //单位： ms
		
		//当buffer写满时，检查文件buffer状态等待的最大
		//时间限制值，这个值应为[WAIT_INTERVAL_WHEN_BUF_FULL]
		//的整数倍
		MAX_WAIT_TIME_WHEN_BUF_FULL = 1000, //单位：ms
	};

private :
	string m_fileName;
	int m_outPutPriority;
	
private:
	static WFW_LogWriter* m_mainLogWriter;
	
public:
	WFW_LogWriter();
	virtual ~WFW_LogWriter();
	
public:
	static WFW_LogWriter* getMainLog();
	static void setMainLog(WFW_LogWriter* mainLog){m_mainLogWriter = mainLog;}
	static WFW_LogWriter* getMainLogWithoutCreate(){return m_mainLogWriter;}
	static void rotateLog(string filePath, int maxFileNum);
	static void syslogOutput(int priority, string msg);
	static void* readerThreadMain(void* arg);

public:
	virtual void write(char* buf, int len);
	void readLoop();
	void log(int priority, const char* format, ...);
	void self_vsprintf(int priority, const char* format, va_list args);
	void perror(int priority, const char* format, ...);
	void start(const string& fileFullName);
	void stop();

public:	
	//void setMaxFileSize(int maxSize){MAX_FILE_SIZE = maxSize;}
	int getMaxFileSize(){return MAX_FILE_SIZE;}
	//void setMaxFileNum(int maxNum){MAX_FILE_NUM = maxNum;}
	int getMaxFileNum(){return MAX_FILE_NUM;}
	void setOutputLogLevel(int level){m_outPutPriority = level;}
	void setFileName(string fileFullName){m_fileName = fileFullName;}
};

#define LOG_FATAL(...) 		WFW_LogWriter::getMainLog()->log(0, __VA_ARGS__)
#define LOG_WARNING(...) 	WFW_LogWriter::getMainLog()->log(1, __VA_ARGS__)
#define LOG_IMPORTANT(...) 	WFW_LogWriter::getMainLog()->log(2, __VA_ARGS__)
#define LOG_INFO(...)		WFW_LogWriter::getMainLog()->log(3, __VA_ARGS__)
#define LOG_DETAIL(...) 	WFW_LogWriter::getMainLog()->log(4, __VA_ARGS__)
#define LOG_DEBUG(...) 		WFW_LogWriter::getMainLog()->log(5, __VA_ARGS__)



#endif
